using Alsing.SourceCode;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using virtuaPol.Model;
using virtuaPol.Util;
using virtuaPol.Main;

namespace virtuaPol.WorldEditor
{
    public partial class FMain : Form
    {

        private enum PropertyTypes
        {
            Integer,
            Decimal,
            Double,
            Boolean,
            String
        }

        private CWorld world;
        // List of pointers to all persons
        private List<CPerson> persons = new List<CPerson>();
        private SyntaxDefinition luaSyntaxDefinition;
        
        public FMain()
        {
            CLogger.Start("log.txt");
            
            InitializeComponent();

            lstCountries.SelectedIndexChanged +=
                new EventHandler(lstCountries_SelectedIndexChanged);
            lstPersons.SelectedIndexChanged +=
                new EventHandler(lstPersons_SelectedIndexChanged);
            lstEvents.SelectedIndexChanged +=
                new EventHandler(lstEvents_SelectedIndexChanged);
            lstProperties.SelectedIndexChanged +=
                new EventHandler(lstProperties_SelectedIndexChanged);
            
            // Fill Event Type combobox
            cbEventType.Items.AddRange(
                Enum.GetNames(typeof(EventType)));

            // Fill Event CheckCycle Unit combobox
            cbEventCheckCycleUnit.Items.AddRange(
                Enum.GetNames(typeof(CheckCycleUnit)));
            
            // Fill Property type combobox
            cbPropertyType.Items.AddRange(
                Enum.GetNames(typeof(CPropertyValueTypes)));

            // Load Lua syntax definition
            editorEventLuaScript.Document = docEventLuaScript;
            try
            {
                SyntaxDefinitionLoader loader = new SyntaxDefinitionLoader();
                luaSyntaxDefinition = loader.Load("Lua.syn");
                editorEventLuaScript.Document.Parser.Init(luaSyntaxDefinition);
            }
            catch (Exception ex)
            {
                CLogger.LogError(ex);
            }
            
            this.Disposed += new EventHandler(FMain_Disposed);

            // Initialize new world
            createNewWorld();
        }

        private void showSplash()
        {
            Splash sp = new Splash();
            sp.ShowDialog();
        }

        void FMain_Disposed(object sender, EventArgs e)
        {
            CLogger.Stop();
        }

        private void refreshCountryList()
        {
            ((CurrencyManager)lstCountries.BindingContext[lstCountries.DataSource]).Refresh();
            cbCountryRelationWith.DataSource = world.Countries.Keys;
            //((CurrencyManager)cbCountryRelationWith.BindingContext[cbCountryRelationWith.DataSource]).Refresh();
        }

        private void refreshCountryPropertyGrid()
        {
            ((CurrencyManager)gridCountryProperties
                .BindingContext[gridCountryProperties.DataSource]).Refresh();
        }

        private void refreshCountryRelationsList()
        {
            ((CurrencyManager)lstCountryRelations.BindingContext[lstCountryRelations.DataSource]).Refresh();
        }

        private void refreshCountryRelationPropertyGrid()
        {
            CCountryRelation r = (CCountryRelation)lstCountryRelations.SelectedItem;
            gridCountryRelationPropertiesNameColumn.DataSource = world.Properties;
            gridCountryRelationPropertiesNameColumn.DisplayMember = "Name";
            gridCountryRelationPropertiesNameColumn.ValueMember = "Name";
            if (r != null)
            {
                gridCountryRelationProperties.DataSource = r.Properties;
                ((CurrencyManager)gridCountryRelationProperties
                    .BindingContext[gridCountryRelationProperties.DataSource]).Refresh();
            }
            else
                gridCountryRelationProperties.DataSource = null;
        }

        private void refreshPersonList()
        {
            ((CurrencyManager)lstPersons.BindingContext[lstPersons.DataSource]).Refresh();
        }

        private void refreshPersonPropertyGrid()
        {
            ((CurrencyManager)gridPersonProperties
                .BindingContext[gridPersonProperties.DataSource]).Refresh();
        }

        private void refreshEventList()
        {
            ((CurrencyManager)lstEvents.BindingContext[lstEvents.DataSource]).Refresh();
        }

        private void refreshPropertyList()
        {
            ((CurrencyManager)lstProperties.BindingContext[lstProperties.DataSource]).Refresh();
            refreshCountryPropertyGrid();
        }

        private void createNewWorld()
        {
            clearUserInterface();
            world = new CWorld("Unnamed");
            populateLists();
            GC.Collect();
        }

        private void populateLists()
        {
            lstPersons.DataSource = persons;
            lstPersons.DisplayMember = "Name";
            lstCountries.DataSource = world.Countries;
            lstCountries.DisplayMember = "Name";
            cbCountryRelationWith.DataSource = world.Countries.Keys;
            cbPersonCountry.DataSource = world.Countries;
            cbPersonCountry.DisplayMember = "Name";
            lstProperties.DataSource = world.Properties;
            lstProperties.DisplayMember = "Name";
            lstEvents.DataSource = world.Events;
            lstEvents.DisplayMember = "Name";
        }

        private void clearUserInterface()
        {
            txtCountryName.Text = "";
            chkPlayable.Checked = false;
            txtPersonName.Text = "";
            txtPropertyDefaultValue.Text = "";
            txtPropertyName.Text = "";
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            createNewWorld();
            GC.Collect();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            clearUserInterface();
            DialogResult result = openFileDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                string extension = Path.GetExtension(openFileDialog.FileName);
                world = null;
                if (!WorldLoader.load(out world, openFileDialog.FileName, extension.Equals(".vpw")))
                {
                    MessageBox.Show("The Worldfile couldn't be opened.",
                        "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    // If the loading operation fails, create new blank world
                    createNewWorld();
                    return;
                }
                this.Text = "vpWorldEditor [" + world.Name + "]";
                // Cleanup memory
                GC.Collect();
            }
            else return;

            // Fill persons list
            foreach(CCountry c in world.Countries)
                persons.AddRange(c.Persons);

            populateLists();
            // Dirty Fix
            refreshPersonList();
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult result = saveFileDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                string extension = Path.GetExtension(saveFileDialog.FileName);
                world.Name = Path.GetFileNameWithoutExtension(saveFileDialog.FileName);
                this.Text = "vpWorldEditor [" + world.Name + "]";
                world.Version++;
                if (!WorldLoader.save(ref world, saveFileDialog.FileName, extension.Equals(".vpw")))
                {
                    MessageBox.Show("The World couldn't be saved to file.",
                        "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
        }

        private void lstCountries_SelectedIndexChanged(object sender, EventArgs e)
        {
            CCountry c = (CCountry)lstCountries.SelectedItem;
            txtCountryName.Text = c.Name;
            chkPlayable.Checked = c.Playable;
            txtCountryDescription.Text = c.Description;
            gridCountryProperties.DataSource = c.Properties;
            gridCountryPropertiesNameColumn.DataSource = world.Properties;
            gridCountryPropertiesNameColumn.DisplayMember = "Name";
            gridCountryPropertiesNameColumn.ValueMember = "Name";
            lstCountryRelations.DataSource = c.Relations;
            lstCountryRelations.DisplayMember = "Name";
        }

        private void lstCountryRelations_SelectedIndexChanged(object sender, EventArgs e)
        {
            CCountryRelation r = (CCountryRelation)lstCountryRelations.SelectedItem;
            cbCountryRelationWith.SelectedItem = r.Name;
            gridCountryRelationProperties.DataSource = r.Properties;
            gridCountryRelationPropertiesNameColumn.DataSource = world.Properties;
            gridCountryRelationPropertiesNameColumn.DisplayMember = "Name";
            gridCountryRelationPropertiesNameColumn.ValueMember = "Name";
        }

        void lstPersons_SelectedIndexChanged(object sender, EventArgs e)
        {
            CPerson p = (CPerson)lstPersons.SelectedItem;
            txtPersonName.Text = p.Name;
            cbPersonCountry.SelectedItem = p.Country;
            gridPersonProperties.DataSource = p.Properties;
            gridPersonPropertiesNameColumn.DataSource = world.Properties;
            gridPersonPropertiesNameColumn.DisplayMember = "Name";
            gridPersonPropertiesNameColumn.ValueMember = "Name";
        }

        void lstEvents_SelectedIndexChanged(object sender, EventArgs e)
        {
            CEvent ev = (CEvent)lstEvents.SelectedItem;
            txtEventName.Text = ev.Name;
            txtEventDescription.Text = ev.Description;
            cbEventType.SelectedItem =
                Enum.GetName(typeof(EventType), ev.Type);
            nudEventCheckCycle.Value = ev.CheckCycle;
            cbEventCheckCycleUnit.SelectedItem =
                Enum.GetName(typeof(CheckCycleUnit), ev.CheckCycleUnit);
            editorEventLuaScript.Document.Text = ev.Script;
        }

        private void lstProperties_SelectedIndexChanged(object sender, EventArgs e)
        {
            CProperty p = (CProperty)lstProperties.SelectedItem;
            txtPropertyName.Text = p.Name;
            cbPropertyType.SelectedItem = Enum.GetName(typeof(CPropertyValueTypes), p.Type);
            txtPropertyDefaultValue.Text = p.Value.ToString();
            txtPropertyDescription.Text = p.Description;
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            createNewWorld();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void btAddCountry_Click(object sender, EventArgs e)
        {
            CCountry c = new CCountry();
            c.Name = "New Country";
            if (!world.addCountry(c))
            {
                MessageBox.Show("You can't add a country right now.", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            // Refresh bindings
            refreshCountryList();
            // Select new country
            lstCountries.SelectedItem = c;
            // Dirty fix
            if (world.Countries.Count == 1)
                lstCountries_SelectedIndexChanged(null, null);

            txtCountryName.Focus();
        }

        private void btDeleteCountry_Click(object sender, EventArgs e)
        {
            CCountry c = (CCountry)lstCountries.SelectedItem;
            if (c.Name.Equals(CWorld.DUMMY_COUNTRY_NAME))
            {
                MessageBox.Show("You can't delete the dummy country.", "Error!",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            int selectedIndex = lstCountries.SelectedIndex;
            world.Countries.Remove(c);
            lstCountries.SelectedIndex = 0;
            // Refresh bindings
            refreshCountryList();
            if (world.Countries.Count > 0 && selectedIndex > 0)
                lstCountries.SelectedIndex = selectedIndex - 1;
        }

        private void btSaveCountry_Click(object sender, EventArgs e)
        {
            CCountry c = (CCountry)lstCountries.SelectedItem;
            if (c.Name.Equals(CWorld.DUMMY_COUNTRY_NAME))
            {
                MessageBox.Show("You can't edit the dummy country.", "Error!",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            c.Name = txtCountryName.Text;
            c.Playable = chkPlayable.Checked;
            c.Description = txtCountryDescription.Text;
            
            // Refresh bindings
            refreshCountryList();
            lstCountries.SelectedItem = c;
        }

        private void btAddCountryProperty_Click(object sender, EventArgs e)
        {
            if (world.Properties.Count == 0)
            {
                MessageBox.Show("There are no properties you could add to this country.",
                    "No Property", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            CCountry c = (CCountry)lstCountries.SelectedItem;
            CProperty dummy = world.getPropertyByName(CWorld.DUMMY_PROPERTY_NAME);
            CProperty p = new CProperty(
                dummy.Name,
                dummy.Type,
                dummy.Value);
            try
            {
                c.Properties.Add(p);
            }
            catch (ArgumentException ex)
            {
                CLogger.LogError(ex);
                MessageBox.Show("That property is already set.", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            catch (Exception ex)
            {
                CLogger.LogError(ex);
                return;
            }
            refreshCountryPropertyGrid();
        }

        private void btDeleteCountryProperty_Click(object sender, EventArgs e)
        {
            CCountry c = (CCountry)lstCountries.SelectedItem;
            string name = (string)gridCountryProperties.SelectedRows[0].Cells[0].Value;
            c.Properties.Remove(name);
            refreshCountryPropertyGrid();
        }

        private void btAddCountryRelation_Click(object sender, EventArgs e)
        {
            CCountry c = (CCountry)lstCountries.SelectedItem;
            CCountryRelation r = new CCountryRelation(world.getCountryByName(CWorld.DUMMY_COUNTRY_NAME));
            if (!c.addRelation(r))
            {
                MessageBox.Show("A relation to the dummy country already exists. Edit this first!", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            // Refresh bindings
            refreshCountryRelationsList();
            // Select new relation
            lstCountryRelations.SelectedItem = r;
            // dirty fix
            /*if (c.Relations.Count == 1)
                lstCountryRelations_SelectedIndexChanged(null, null);*/
        }

        private void btRemoveCountryRelation_Click(object sender, EventArgs e)
        {
            CCountry c = (CCountry)lstCountries.SelectedItem;
            CCountryRelation r = (CCountryRelation)lstCountryRelations.SelectedItem;

            int selectedIndex = lstCountryRelations.SelectedIndex;
            c.removeRelation(r);
            lstCountryRelations.SelectedIndex = 0;
            // Refresh bindings
            refreshCountryRelationsList();
            if (c.Relations.Count > 0 && selectedIndex > 0)
                lstCountryRelations.SelectedIndex = selectedIndex - 1;
            else
            {
                cbCountryRelationWith.SelectedIndex = 0;
                refreshCountryRelationPropertyGrid();
            }
        }

        private void btSaveCountryRelation_Click(object sender, EventArgs e)
        {
            CCountry c = (CCountry)lstCountries.SelectedItem;
            CCountryRelation r = (CCountryRelation)lstCountryRelations.SelectedItem;
            string newName = (string)cbCountryRelationWith.SelectedValue;
            if (newName == c.Name)
            {
                MessageBox.Show("A country can't have a relationship with itself.", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            r.Name = newName;
            // refresh bindings
            refreshCountryRelationsList();
            lstCountryRelations.SelectedItem = r;
        }

        private void btCountryRelationAddProperty_Click(object sender, EventArgs e)
        {
            if (world.Properties.Count == 0)
            {
                MessageBox.Show("There are no properties you could add to this relation.",
                    "No Property", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            CCountryRelation r = (CCountryRelation)lstCountryRelations.SelectedItem;
            CProperty dummy = world.getPropertyByName(CWorld.DUMMY_PROPERTY_NAME);
            CProperty p = new CProperty(
                dummy.Name,
                dummy.Type,
                dummy.Value);
            try
            {
                r.Properties.Add(p);
            }
            catch (ArgumentException ex)
            {
                CLogger.LogError(ex);
                MessageBox.Show("That property is already set.", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            catch (Exception ex)
            {
                CLogger.LogError(ex);
                return;
            }
            refreshCountryRelationPropertyGrid();
        }

        private void btCountryRelationRemoveProperty_Click(object sender, EventArgs e)
        {
            CCountryRelation r = (CCountryRelation)lstCountryRelations.SelectedItem;
            string name = (string)gridCountryRelationProperties.SelectedRows[0].Cells[0].Value;
            r.Properties.Remove(name);
            refreshCountryRelationPropertyGrid();
        }

        private void btAddPerson_Click(object sender, EventArgs e)
        {
            CPerson p = new CPerson("New Person");
            world.Countries[CWorld.DUMMY_COUNTRY_NAME].addPerson(p);
            persons.Add(p);
            refreshPersonList();
            // Select new country
            lstPersons.SelectedItem = p;
            // Dirty fix
            if (persons.Count == 1)
                lstPersons_SelectedIndexChanged(null, null);

            txtPersonName.Focus();
        }

        private void btDeletePerson_Click(object sender, EventArgs e)
        {
            int selectedIndex = lstPersons.SelectedIndex;
            CPerson p = (CPerson)lstPersons.SelectedItem;
            persons.Remove(p);
            p.Country.removePerson(p);
            lstPersons.SelectedIndex = 0;
            // Refresh bindings
            refreshPersonList();
            if (persons.Count > 0 && selectedIndex > 0)
                lstPersons.SelectedIndex = selectedIndex - 1;
        }

        private void btSavePerson_Click(object sender, EventArgs e)
        {
            CPerson p = (CPerson)lstPersons.SelectedItem;
            p.Name = txtPersonName.Text;
            p.Description = txtPersonDescription.Text;
            world.movePerson(p, p.Country, (CCountry)cbPersonCountry.SelectedItem);

            // Refresh bindings
            refreshPersonList();
            lstPersons.SelectedItem = p;
        }

        private void btAddPersonProperty_Click(object sender, EventArgs e)
        {
            if (world.Properties.Count == 0)
            {
                MessageBox.Show("There are no properties you could add to this person.",
                    "No Property", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            CPerson person = (CPerson)lstPersons.SelectedItem;
            CProperty dummy = world.getPropertyByName(CWorld.DUMMY_PROPERTY_NAME);
            CProperty p = new CProperty(
                dummy.Name,
                dummy.Type,
                dummy.Value);
            try
            {
                person.Properties.Add(p);
            }
            catch (ArgumentException ex)
            {
                CLogger.LogError(ex);
                MessageBox.Show("That property is already set.", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            catch (Exception ex)
            {
                CLogger.LogError(ex);
                return;
            }
            refreshPersonPropertyGrid();
        }

        private void btDeletePersonProperty_Click(object sender, EventArgs e)
        {
            CPerson p = (CPerson)lstPersons.SelectedItem;
            string name = (string)gridPersonProperties.SelectedRows[0].Cells[0].Value;
            p.Properties.Remove(name);
            refreshPersonPropertyGrid();
        }

        private void btAddEvent_Click(object sender, EventArgs e)
        {
            CEvent ev = new CEvent("New Event");
            if (!world.addEvent(ev))
            {
                MessageBox.Show("You can't add an event right now.", "Error!",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            refreshEventList();
            lstEvents.SelectedItem = ev;
            // Dirty fix
            if (world.Events.Count == 1)
                lstEvents_SelectedIndexChanged(null, null);

            txtEventName.Focus();
        }

        private void btDeleteEvent_Click(object sender, EventArgs e)
        {
            int selectedIndex = lstEvents.SelectedIndex;
            CEvent ev = (CEvent)lstEvents.SelectedItem;
            world.Events.Remove(ev);
            lstEvents.SelectedIndex = 0;
            refreshEventList();
            if (world.Events.Count > 0)
                lstEvents.SelectedIndex = selectedIndex;
        }

        private void btSaveEvent_Click(object sender, EventArgs e)
        {
            CEvent ev = (CEvent)lstEvents.SelectedItem;
            ev.Name = txtEventName.Text;
            ev.Description = txtEventDescription.Text;
            try
            {
                ev.Type = (EventType)Enum.Parse(typeof(EventType),
                    (string)cbEventType.SelectedItem);
            }
            catch (ArgumentException ex)
            {
                ev.Type = EventType.Silent;
            }
            ev.CheckCycle = (int)nudEventCheckCycle.Value;
            try
            {
                ev.CheckCycleUnit = (CheckCycleUnit)Enum.Parse(typeof(CheckCycleUnit),
                        (string)cbEventCheckCycleUnit.SelectedItem);
            }
            catch (ArgumentException ex)
            {
                ev.CheckCycleUnit = CheckCycleUnit.Seconds;
            }
            ev.Script = editorEventLuaScript.Document.Text;

            refreshEventList();
            lstEvents.SelectedItem = ev;
        }

        private void btAddProperty_Click(object sender, EventArgs e)
        {
            CProperty p = new CProperty("New Property", CPropertyValueTypes.Integer, 0);
            if(!world.addProperty(p))
            {
                MessageBox.Show("You can't add a property right now.", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            
            // Refresh bindings
            refreshPropertyList();
            // Select new property
            lstProperties.SelectedItem = p;
            // Dirty fix
            if (world.Properties.Count == 1)
                lstProperties_SelectedIndexChanged(null, null);

            txtPropertyName.Focus();
        }

        private void btDeleteProperty_Click(object sender, EventArgs e)
        {
            CProperty p = (CProperty)lstProperties.SelectedItem;
            if (p.Name.Equals(CWorld.DUMMY_PROPERTY_NAME))
            {
                MessageBox.Show("You can't delete the dummy property.", "Error!",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            int selectedIndex = lstProperties.SelectedIndex;
            world.Properties.Remove(p);
            lstProperties.SelectedIndex = 0;
            refreshPropertyList();
            if (world.Properties.Count > 0 && selectedIndex > 0)
                lstProperties.SelectedIndex = selectedIndex - 1;
            else
            {
                txtPropertyName.Text = "";
                txtPropertyDefaultValue.Text = "";
            }
        }

        private void btSaveProperty_Click(object sender, EventArgs e)
        {
            CProperty p = (CProperty)lstProperties.SelectedItem;
            if (p.Name.Equals(CWorld.DUMMY_PROPERTY_NAME))
            {
                MessageBox.Show("You can't edit the dummy property.", "Error!",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            CPropertyValueTypes newType = (CPropertyValueTypes)Enum.Parse(
                typeof(CPropertyValueTypes), (string)cbPropertyType.SelectedItem);

            string newValue = txtPropertyDefaultValue.Text;
            
            // Update property names in country objects if name has changed
            if (p.Name != txtPropertyName.Text)
            {
                foreach (CCountry c in world.Countries)
                {
                    if (c.Properties.Contains(p.Name))
                    {
                        CProperty newP;
                        // if type changed, reset type and value to default value
                        try
                        {
                            newP = new CProperty(
                                txtPropertyName.Text,
                                p.Type,
                                c.Properties[p.Name].Value);
                        }
                        catch (InvalidCastException ex)
                        {
                            // The conversion was impossible. Set value to default value.
                            newP = new CProperty(
                                txtPropertyName.Text, newType, newValue);
                        }
                        newP.Description = txtPropertyDescription.Text;

                        c.Properties.Remove(p.Name);
                        c.Properties.Add(newP);
                    }
                }
            }

            p.Name = txtPropertyName.Text;
            p.Description = txtPropertyDescription.Text;
            p.Type = newType;
            p.Value = newValue;

            
            // Refresh bindings
            refreshPropertyList();
            lstProperties.SelectedItem = p;
        }

        private void btEventTestScript_Click(object sender, EventArgs e)
        {
            EventScriptTester tester =
                new EventScriptTester(new CWorld("Test World"), editorEventLuaScript.Document.Text);
            if(tester.Test())
                MessageBox.Show(
                    "The test was successful.",
                    "Test successful",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
        }

        

        private void gridProperties_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 0)
            {
                CProperty newP = (CProperty)((DataGridView)sender).Rows[e.RowIndex].DataBoundItem;
                CProperty p = world.getPropertyByName(newP.Name);
                if (p == null)
                    return;
                newP.Type = p.Type;
                try
                {
                    newP.FixValueType();
                }
                catch (InvalidCastException ex)
                {
                    newP.Value = p.Value;
                }
            }
        }
    }
}